package cn.highset.modules.base.serviceimpl;

import cn.highset.common.constant.CommonConstant;
import cn.highset.common.vo.SearchVo;
import cn.highset.modules.base.dao.ProductTypeDao;
import cn.highset.modules.base.entity.ProductType;
import cn.highset.modules.base.service.ProductTypeService;
import cn.highset.redis.client.RedisClient;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 产品类别接口实现
 *
 * @author Victor
 */
@Slf4j
@Service
@Transactional
public class ProductTypeServiceImpl implements ProductTypeService {

    @Autowired
    private ProductTypeDao productTypeDao;
    @Autowired
    private RedisClient redisClient;

    @Override
    public ProductTypeDao getRepository() {
        return productTypeDao;
    }

    @Override
    public Page<ProductType> findByCondition(ProductType productType, SearchVo searchVo, Pageable pageable) {

        return productTypeDao.findAll(new Specification<ProductType>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<ProductType> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                // TODO 可添加你的其他搜索过滤条件 默认已有创建时间过滤
                Path<Date> createTimeField = root.get("createTime");

                List<Predicate> list = new ArrayList<Predicate>();

                //创建时间
                if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
                    Date start = DateUtil.parse(searchVo.getStartDate());
                    Date end = DateUtil.parse(searchVo.getEndDate());
                    list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                }

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        }, pageable);
    }

    @Override
    public List<ProductType> findByParentIdOrderBySortOrder(String parentId) {

        List<ProductType> list = new ArrayList<>();
        String key = "productType::" + parentId;
        Object v = redisClient.string().get(key);
        if (v != null) {
            return (List<ProductType>) v;
        }
//        String v = redisTemplate.opsForValue().get(key);
//        if (StrUtil.isNotBlank(v)) {
//            list = new Gson().fromJson(v, new TypeToken<List<ProductType>>() {
//            }.getType());
//            return list;
//        }
        list = productTypeDao.findByParentIdOrderBySortOrder(parentId);
        list = setInfo(list);
        redisClient.string().set(key, list);
//        redisTemplate.opsForValue().set(key,
//                new GsonBuilder().registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY).create().toJson(list));

        return list;
    }

    @Override
    public List<ProductType> findByNameCnLikeOrderBySortOrder(String nameCn) {
        return productTypeDao.findByNameCnLikeOrderBySortOrder(nameCn);
    }

    @Override
    public List<ProductType> setInfo(List<ProductType> list) {
        // lambda表达式
        list.forEach(item -> {
            item.setTitle(item.getNameCn());
            if (!CommonConstant.PARENT_ID.equals(item.getParentId())) {
                ProductType parent = get(item.getParentId());
                item.setParentTitle(parent.getNameCn());
            } else {
                item.setParentTitle("一级类别");
            }
        });
        return list;
    }
}
